#ifndef PUBLIC_H
#define PUBLIC_H

//全局定义以及方法 zxt

extern "C"
{
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libavutil/imgutils.h"
#include "libswscale/swscale.h"
#include "libavdevice/avdevice.h"
#include "libavutil/time.h"
#include "libavfilter/avfilter.h"
#include "libavfilter/buffersrc.h"
#include "libavfilter/buffersink.h"
#include "libavutil/log.h"
}

#include <string>
#include <iostream>
#include <sys/time.h>
#include "mk_util.h"
using namespace std;

#define LOG_LEV 4

enum ENUM_CAMERATYPE
{
    CAMERA_NONE = 0,
    CAMERA_SG = 1,
    CAMERA_QJ = 2,
    CAMERA_DP = 3,
    CAMERA_UAVSG = 4
};

enum ENUM_MEDIATYPE
{
    MEDIA_NONE = 0,
    MEDIA_VIDEO = 1,
    MEDIA_AUDIO = 2,
    MEDIA_ALL = 3
};

//相机媒体源配置信息
struct STU_CAMERAINFO
{
    //使能该相机
    int enable = 0;
    //使能录制
    int record = 0;
    //媒体源信息
    string sourceUrl;
    //1双光 2全景 3底盘 4无人机
    int cameraType = 0;
    string cameraName;
    //输出流信息
    string app;
    string stream;

    //协议类型 usb相机时下方参数生效
    //0-rtsp 如rtsp://192.168.1.100:554/app-name/stream-name
    //1-file 如/opt/media/test.mp4
    //10-usb相机 通用平台 cpu ffmpeg采集 + ffmpeg转换 + ffmpeg编码      arm下采用libyuv转换
    //11-usb相机 通用平台 cpu v4l2采集 + ffmpeg转换 + ffmpeg编码        arm下采用libyuv转换
    //12-usb相机 通用平台 gpu v4l2采集 + ffmpeg转换 + ffmpeg硬件编码     arm下采用libyuv转换
    //13-usb相机 瑞芯微   gpu v4l2采集 + rga转换 + mpp编码
    int protocal = 0;

    //usb设备输入信息 协议类型为1时下方参数有效
    string devName;
    int inWidth = 640;
    int inHeight = 480;
    int inFPS = 25;
    //输出信息
    int outWidth = 1280;
    int outHeight = 720;
    int outFPS = 25;
    int outH264 = 1;
    int outBitrate = 1024000;
};

//录制文件信息
struct STU_FILEINFO
{
    int mediaType = MEDIA_VIDEO;
    int cameraType = CAMERA_NONE;
    string cameraName;

    string fileName;     //文件名
    string path;         //文件路径
    uint size;           //文件大小-M
    string startTime;    //文件开始时间
    string stoptime;     //文件结束时间
    uint64_t createTime; //文件开始时间 ms时间戳 since 1970...
    uint duration;       //文件时长-S
};

//输出参数
struct STU_PUSHPARAM
{
    string srcUrl;         //媒体源
    int inWidth = 1280;    //宽度
    int inHeight = 720;    //高度
    int inFPS = 25;        //帧率
    string deviceName = "/dev/video0"; //设备信息
    int outWidth = 1280;   //宽度
    int outHeight = 720;   //高度
    int outFPS = 25;       //帧率
    int bFrame = 0;        //无B帧
    int isH264 = 1;        //默认264
    AVPixelFormat pixFmt = AV_PIX_FMT_YUV420P; //编码图像格式
    int bitRate = 1024000;       //输出码率 默认1Mbps
    int threadsCount = 2;        //编码器线程数量
    string preset = "ultrafast"; //预设编码速度
    string tune = "zerolatency"; //预设编码延时参数
    int record = 0;              //录制
    string app = "usbcamera";    //媒体源标识
    string stream = "main";
};

//时间转格式化字符串
string getStyleTime(time_t t);
string getStyleTime();
string getStyleTimeMS();
void getFFmpegError(int errnum);
string getFFmpegErrroStr(int errnum);
tm *getCurDatetime();

//yuyv422文件类
class YUYV422FileWriter
{
public:
    YUYV422FileWriter(string path = "yuyv422.yuyv", int maxSize = -1);
    ~YUYV422FileWriter();

    //写数据 超过大小自动停止
    int writeYUYV422Data(const char *data, unsigned int size);

public:
    FILE *m_file = nullptr;
    int m_maxSize = 0;
    int m_totalSize = 0;
};

class YUV420PFileWriter
{
public:
    YUV420PFileWriter(string path = "yuv420.yuv", int maxSize = -1);
    ~YUV420PFileWriter();

    //写数据 超过大小自动停止
    int writeYUV420PData(AVFrame *frame);

public:
    FILE *m_file = nullptr;
    int m_maxSize = 0;
    int m_totalSize = 0;
};

#endif // PUBLIC_H
